package tr.edu.bilgi.videocs;

import java.util.ArrayList;
import java.util.Locale;

import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import tr.edu.bilgi.videocs.db.DatabaseHelper;
import tr.edu.bilgi.videocs.models.Speaker;
import tr.edu.bilgi.videocs.models.Video;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;

public class Main extends Activity implements OnClickListener {
  private SQLiteDatabase db;
  private static final String TAG = "Main";

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {

    // Initialize database
    // deleteDatabase("Testing.db");
    db = openOrCreateDatabase("Testing.db", SQLiteDatabase.CREATE_IF_NECESSARY,
        null);
    db.setVersion(1);
    db.setLocale(Locale.getDefault());
    db.setLockingEnabled(true);
    try {

      final String CREATE_TABLE_VIDEOS = "create table videos ("
          + "id text primary key, " + "title text, " + "speaker text, "
          + "series text, " + "thumb text, " + "url text" + ")";
      db.execSQL(CREATE_TABLE_VIDEOS);

      final String CREATE_TABLE_SPEAKERS = "create table speakers ("
          + "name text primary key)";
      db.execSQL(CREATE_TABLE_SPEAKERS);

      final String CREATE_TABLE_SERIES = "create table series ("
          + "id text primary key)";
      db.execSQL(CREATE_TABLE_SERIES);
    } catch (Exception e) {
    }

    super.onCreate(savedInstanceState);
    setContentView(R.layout.dashboard);

    View allVideos = this.findViewById(R.id.allVideos);
    allVideos.setOnClickListener(this);

    // View allSpeakers = this.findViewById(R.id.allSpeakers);
    // allSpeakers.setOnClickListener(this);

    View allSeries = this.findViewById(R.id.allSeries);
    allSeries.setOnClickListener(this);

    // Get the videos from the site
    String responseBody = null;
    HttpClient httpclient = new DefaultHttpClient();

    try {
      HttpGet httpget = new HttpGet("http://video.cs.bilgi.edu.tr/infos/list");
      System.out.println("executing request " + httpget.getURI());
      // Create a response handler
      ResponseHandler<String> responseHandler = new BasicResponseHandler();
      responseBody = httpclient.execute(httpget, responseHandler);
    } catch (Exception e) {
      responseBody = OfflineData.list;
      Log.w(TAG,
          "Cannot connect to the videos site. Fallbacking to the offline data.");
    } finally {
      httpclient.getConnectionManager().shutdown();
    }

    // Remove me
    for (String line : responseBody.split("\\n")) {
      updateVideoData(line);
      Log.d(TAG, line);
    }

    Log.d(TAG, db.toString());
  }

  private void updateVideoData(String videoId) {
    HttpClient httpclient = new DefaultHttpClient();
    String responseBody = null;

    try {
      HttpGet httpget = new HttpGet("http://video.cs.bilgi.edu.tr/infos/"
          + videoId + ".json");
      System.out.println("executing request " + httpget.getURI());
      // Create a response handler
      ResponseHandler<String> responseHandler = new BasicResponseHandler();
      responseBody = httpclient.execute(httpget, responseHandler);
    } catch (Exception e) {
      responseBody = OfflineData.videoInfo.get(videoId);
    } finally {
      httpclient.getConnectionManager().shutdown();
    }

    try {
      JSONObject videoJson = new JSONObject(responseBody);
      insertOrUpdateRow(videoJson);
      Log.d(TAG, videoJson.getString("title"));
    } catch (JSONException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

  }

  private void insertOrUpdateRow(JSONObject videoJson) throws JSONException {
    ContentValues values = new ContentValues();
    String seriesId = null;
    String speakerName = null;

    // Get video attributes
    String videoId = videoJson.getString("vid");
    values.put("id", videoId);
    values.put("title", videoJson.getString("title"));
    values.put("thumb", "http://video.cs.bilgi.edu.tr/thumbs/big/" + videoId
        + ".png");
    values.put("url", "http://video.cs.bilgi.edu.tr/videos/" + videoId
        + ".3gpp");

    // Try to get series
    JSONObject seriesJson = videoJson.getJSONObject("series");
    if (seriesJson != null) {
      seriesId = seriesJson.getString("sid");
      if (seriesId != null) {
        ContentValues seriesValues = new ContentValues();
        seriesValues.put("id", seriesId);
        try {
          db.insertOrThrow("series", null, seriesValues);
          Log.d(TAG, "Inserted series named: " + seriesId);
        } catch (SQLiteConstraintException e) {
          // This happens when this series is already in the db
          Log.d(TAG, "Series already exists: " + seriesId);
        }
      }
    }

    // Try to get speakers
    JSONArray speakersJson = videoJson.getJSONArray("speakers");
    if (speakersJson != null && speakersJson.length() != 0) {
      // We only get the first speaker
      speakerName = speakersJson.getString(0);
      if (speakerName != null) {
        ContentValues speakerValues = new ContentValues();
        speakerValues.put("name", speakerName);
        try {
          db.insertOrThrow("speakers", null, speakerValues);
          Log.d(TAG, "Inserted speaker named: " + speakerName);
        } catch (SQLiteConstraintException e) {
          // This happens when this speaker is already in the db
          Log.d(TAG, "Speaker already exists: " + speakerName);
        }
      }
    }

    // Attach series and speakers to the video
    if (seriesId != null) {
      values.put("series", seriesId);
    }

    if (speakerName != null) {
      values.put("speaker", speakerName);
    }

    try {
      db.insertOrThrow("videos", null, values);
      Log.d(TAG, "Inserted video: " + videoId);
    } catch (SQLiteConstraintException e) {
      // This happens when this video is already in the db
      Log.d(TAG, "Video already exists: " + videoId);
    } catch (Exception e) {
      Log.d(TAG, e.toString());
    }
  }

  // @Override
  public void onClick(View v) {
    switch (v.getId()) {
    case R.id.allVideos:
      Intent intent = new Intent(this, VideoList.class);
      intent.putExtra("videos", getAllVideos());
      startActivity(intent);
      break;
    // case R.id.allSpeakers:
    // Intent i2 = new Intent(this, SpeakerList.class);
    // startActivity(i2);
    // break;
    // case R.id.allSeries:
    // Intent i3 = new Intent(this, NewsList.class);
    // startActivity(i3);
    // break;
    // More buttons go here (if any) ...
    }

  }

  private Speaker getSpeaker(String id) {
    Speaker speaker = new Speaker();
    Cursor cursor = db.query("speakers", null, "name = '" + id + "'", null,
        null, null, null);
    cursor.moveToFirst();
    speaker.setId(cursor.getString(0));
    speaker.setName(cursor.getString(0));
    cursor.close();
    return speaker;
  }

  private ArrayList<Video> getAllVideos() {
    ArrayList<Video> videos = new ArrayList<Video>();
    Cursor cursor = db.query("videos", null, null, null, null, null, null);
    cursor.moveToFirst();
    while (cursor.isAfterLast() == false) {
      Video video = new Video();
      video.setId(cursor.getString(0));
      video.setTitle(cursor.getString(1));
      video.setSpeaker(getSpeaker(cursor.getString(2)));
      video.setThumbnailUrl(cursor.getString(4));
      video.setVideoUrl(cursor.getString(5));

      videos.add(video);
      cursor.moveToNext();
    }
    cursor.close();
    Log.d(TAG, "--------");
    Log.d(TAG, videos.toString());
    Log.d(TAG, "--------");

    // Log.d(TAG, ((Video[]) videos.toArray()).toString());
    return videos;
  }
}
